import { fnError } from '..'
import base64 from './base64'
import type { IOssModel } from './browserUpload'
import Crypto from './crypto'

function miniUpload(filePath: string, ossInfo: IOssModel): Promise<string> {
  const aliyunFileKey = ossInfo.path + new Date().getTime() + filePath.split('/').pop()
  const aliyunServerURL = `https://${ossInfo.Bucket}.${ossInfo.EndPoint}/` // OSS地址，需要https
  const accessid = ossInfo.Credentials.AccessKeyId
  const policyBase64 = getPolicyBase64(ossInfo.Credentials.Expiration)
  const signature = getSignature(policyBase64, ossInfo.Credentials.AccessKeySecret) // 获取签名
  return new Promise<string>((resolve, reject) => {
    const error = new Error('上传失败')
    uni.uploadFile({
      url: aliyunServerURL,
      filePath,
      fileType: 'image',
      name: 'file',
      timeout: 15e3,
      formData: {
        key: aliyunFileKey,
        policy: policyBase64,
        OSSAccessKeyId: accessid,
        'x-oss-security-token': ossInfo.Credentials.SecurityToken,
        signature,
        success_action_status: '200',
      },
      success: (res: any) => {
        if (res.statusCode === 200) {
          const url = ossInfo.OssUrl + aliyunFileKey
          console.log('上传成功', url)
          resolve(url)
        } else {
          fnError(error)
          reject(error)
        }
      },
      fail: (err) => {
        console.warn(err)
        fnError(error)
        reject(err)
      },
    })
  })
}

export function getPolicyBase64(expiration: string): string {
  const policyText = {
    expiration, // 设置该Policy的失效时间，超过这个失效时间之后，就没有办法通过这个policy上传文件了
    conditions: [
      ['content-length-range', 0, 50 * 1024 * 1024], // 设置上传文件的大小限制,50mb
    ],
  }

  const policyBase64 = base64.encode(JSON.stringify(policyText))
  return policyBase64
}

export function getSignature(policyBase64: string, accesskey: string) {
  const bytes = Crypto.util.HMAC(Crypto.util.SHA1, policyBase64, accesskey, {
    asBytes: true,
  })
  const signature = Crypto.util.bytesToBase64(bytes)
  return signature
}

export default miniUpload
